package com.marvels.approve.process.service.impl;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.marvels.approve.common.dto.CmsEmployeeInfoDTO;
import com.marvels.approve.common.service.ISysUserService;
import com.marvels.approve.common.service.McamLoanApplyInfoCommonService;
import com.marvels.approve.consum.ApproveConsumerUmApi;
import com.marvels.approve.loan.dao.IMcamLoanApplyInfoDao;
import com.marvels.approve.loan.dto.McamLoanApplyInfoDTO;
import com.marvels.approve.process.dao.IFaceSigAppointmentDao;
import com.marvels.approve.process.dao.IFaceSigConfiguractionDao;
import com.marvels.approve.process.dao.ILoanApplyCaseLogDao;
import com.marvels.approve.process.dto.FaceSigAppointmentDTO;
import com.marvels.approve.process.dto.FaceSigConfigurationDTO;
import com.marvels.approve.process.dto.HandleProcessDTO;
import com.marvels.approve.process.dto.LoanApplyCaseDTO;
import com.marvels.approve.process.dto.LoanApplyCaseLogDTO;
import com.marvels.approve.process.dto.SysUserDTO;
import com.marvels.approve.process.service.IFaceSigAppointmentService;
import com.marvels.approve.process.service.IFaceSigConfigurationService;
import com.marvels.approve.process.service.IProcessService;
import com.marvels.common.constants.CaseNodeConstant;
import com.marvels.common.constants.FacesigOperationType;
import com.marvels.common.constants.LoanStateConstant;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.constants.PageConstant;
import com.marvels.common.dto.ChannelUserDTO;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;
import com.marvels.common.utils.ThreadContextUtil;

/**
 * 视频面签服务
 * 
 */
@Service
public class FaceSigAppointmentServiceImpl implements IFaceSigAppointmentService {
	@Autowired
	private IFaceSigAppointmentDao faceSigAppointmentDao;

	@Autowired
	private IProcessService processService;

	@Autowired
	private ISysUserService iSysUserService;
	
	@Autowired
	private IFaceSigConfiguractionDao faceSigConfiguractionDao;
	
    @Autowired
	private IMcamLoanApplyInfoDao mcamLoanApplyInfoDao;
    @Autowired
    private ApproveConsumerUmApi consumerUmApi;
    @Autowired
    private IFaceSigConfigurationService faceSigConfigurationService;
    @Autowired
    private ILoanApplyCaseLogDao loanApplyCaseLogDao;
    @Autowired
	private McamLoanApplyInfoCommonService mcamLoanApplyInfoCommonService;
    @Value("${config.properties.path}")
	private String propertiesPath;
    
	@Override
	public Page<FaceSigAppointmentDTO> getFaceSigAppointmentPage(FaceSigAppointmentDTO faceSigAppointmentDTO,
			Integer pageNo, Integer pageSize) throws MarvelsBusinessException {
		faceSigAppointmentDTO = faceSigAppointmentDTO == null ? new FaceSigAppointmentDTO() : faceSigAppointmentDTO;
		if (pageNo <= 0) {
			pageNo = PageConstant.CURRPAGE;
		}
		if (pageSize <= 0) {
			pageSize = PageConstant.PAGESIZE;
			
		}
		PageHelper.startPage(pageNo, pageSize);
		Page<FaceSigAppointmentDTO> faceSigPage = faceSigAppointmentDao.selectFaceSigPage(faceSigAppointmentDTO);
		return faceSigPage;
	}

	@Override
	public FaceSigAppointmentDTO findFaceSigStatus() throws MarvelsBusinessException {
		UserDTO user = CacheUtils.getCacheUser();  //从缓存中读取到用户
		String userCode =user.getUserCode() == null?MarvelsConstant.SYSTEM_USER : user.getUserCode();
		return this.faceSigAppointmentDao.selectFaceSigStatus(userCode);
	}
	/**
	 * 新建面签任务
	 */
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	@Override
	public Integer addFacesigTask(FaceSigAppointmentDTO faceSigAppointmentDTO) throws MarvelsBusinessException {
		String custName = faceSigAppointmentDTO.getCustName();
		if(StringUtils.isEmpty(custName)){
			throw new MarvelsBusinessException("客户姓名不能为空");
		}
		String idCardNo = faceSigAppointmentDTO.getCustIdcard();
		if(StringUtils.isEmpty(idCardNo)){
			throw new MarvelsBusinessException("客户证件号码不能为空");
		}
		String mobileNo = faceSigAppointmentDTO.getCustMobile();
		if(StringUtils.isEmpty(mobileNo)){
			throw new MarvelsBusinessException("客户手机号码不能为空");
		}
		Integer timeId = faceSigAppointmentDTO.getTimeId();
		if(timeId==null){
			throw new MarvelsBusinessException("预约时间段不能为空");
		}
		//获取面签时间配置
		FaceSigConfigurationDTO faceSigConfiguration = faceSigConfiguractionDao.selectByPrimaryKey(faceSigAppointmentDTO.getTimeId());
		if(faceSigConfiguration==null){
			throw new MarvelsBusinessException("没有对应的面签时间配置");
		}
		
		Time startTime = faceSigConfiguration.getStartTime();
		SimpleDateFormat df = new SimpleDateFormat("HH-mm-ss");
		String startTimeStr = df.format(startTime);
		//获取生效时间
		Date startDate = faceSigAppointmentDTO.getStartTime();
		String startDateStr = DateUtils.getDateYYYY_MM_DD(startDate);
		Date date = DateUtils.parseString(startDateStr+" "+startTimeStr);
		//校验
		if(date.getTime()<new Date().getTime()){
			throw new MarvelsBusinessException("不可预约过去的时间");
		}
		//可以处理面签任务的人数(建好分组后获取)
		List<SysUserDTO> userList = this.selectFaceSignUsers();
		if(CollectionUtils.isEmpty(userList)){
			throw new MarvelsBusinessException("没有可以面签的人员！");
		}
		Integer canFacesignNumber = userList.size();
		//已经预约的人数
		FaceSigAppointmentDTO faceSignDto = new FaceSigAppointmentDTO();
		faceSignDto.setTimeId(faceSigAppointmentDTO.getTimeId());
		faceSignDto.setAppointmentDate(new Date());
		Integer hasBookNumber = this.queryDateTimeCount(faceSignDto);
		//可调整人数
		String canAdjustStr = ServerProperties.getValue(propertiesPath, "resource.properties", "facesign.adjust.count");
		Integer canAdjustNumber  = 0;
		if(!StringUtils.isEmpty(canAdjustStr)){
			canAdjustNumber = Integer.parseInt(canAdjustStr);
		}
		if(canFacesignNumber-canAdjustNumber<=hasBookNumber){
			throw new MarvelsBusinessException("没有可以预约的坐席了！");
		}
		McamLoanApplyInfoDTO loanApplyInfoDTO = new McamLoanApplyInfoDTO();
		loanApplyInfoDTO.setStatus(LoanStateConstant.P01);
		List<McamLoanApplyInfoDTO> applyInfoList = mcamLoanApplyInfoDao.select(loanApplyInfoDTO);
		if(CollectionUtils.isEmpty(applyInfoList)){
			throw new MarvelsBusinessException("没有可以预约的客户！");
		}
		//判断该客户录入的信息是否与系统匹配
		McamLoanApplyInfoDTO canSubscribeApplyInfo =null;
		for(McamLoanApplyInfoDTO dto:applyInfoList){
			if(custName.equals(dto.getCustName())&&idCardNo.equals(dto.getCustCardNo())&&mobileNo.equals(dto.getMobileNo())){
				canSubscribeApplyInfo = dto;
				break;
			}
		}
		if(canSubscribeApplyInfo == null){
			throw new MarvelsBusinessException("该客户信息不匹配，不可预约");
		}
		//获取面签人员是否有未完成的任务
		Integer undoTaskCount = faceSigAppointmentDao.selectUndoSignTask(faceSigAppointmentDTO.getFaceJobId());
		if(undoTaskCount>0){
			throw new MarvelsBusinessException("该面签人员有未完成任务!");
		}
		ChannelUserDTO user = consumerUmApi.queryUserById(Integer.parseInt(canSubscribeApplyInfo.getEmployeeId()));
		
		///////////////////////////////////////////////////////////////////////////
		if(!StringUtils.isEmpty(faceSigAppointmentDTO.getFaceJobId())){
			HandleProcessDTO handleProcessDTO = new HandleProcessDTO();
			List<String> queryNodes = new ArrayList<String>();
			queryNodes.add(CaseNodeConstant.WOINTERVIEW.getCode());
			handleProcessDTO.setQueryNodes(queryNodes);
			handleProcessDTO.setLoanId(canSubscribeApplyInfo.getLoanId());
			LoanApplyCaseDTO loanApplyCase = processService.handleProcess(handleProcessDTO);
			if (loanApplyCase == null) {
				throw new MarvelsBusinessException("新增面签任务执行工作流失败" + loanApplyCase);
			}
		}
		//////////////////////////////////////////////////
		this.doAppointment(user, canSubscribeApplyInfo, faceSigAppointmentDTO.getTimeId(), faceSigAppointmentDTO.getStartTime(),faceSigAppointmentDTO.getFaceJobId(),true);
		
		return 1;
	}

	/**
	 * 取件
	 */
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	@Override
	public Integer takeFacesig(LoanApplyCaseDTO loanApplyCaseDTO) throws MarvelsBusinessException {
		Integer count = 0;
		UserDTO user = CacheUtils.getCacheUser();  //从缓存中读取到用户
		String userCode =user.getUserCode() == null?MarvelsConstant.SYSTEM_USER : user.getUserCode();
		//需要校验是否有预约
		List<FaceSigAppointmentDTO> faceSigns = faceSigAppointmentDao.selectAllNeedPickUpCase(CaseNodeConstant.WOINTERVIEW.getCode());
		if(CollectionUtils.isEmpty(faceSigns)){
			throw new MarvelsBusinessException("无可取单"+userCode);
		}
		// 取件规则：同一视频预约时间段内的数据，一次只能取一条；如12月7日15:00-16:00有2条数据，面签人员A点击取件后会取出一条数据，再次点击取件只能取出非该时间段内的数据；
		Iterator<FaceSigAppointmentDTO> iterator = faceSigns.iterator();
		FaceSigAppointmentDTO dto = null;
		while(iterator.hasNext()){
			FaceSigAppointmentDTO faceSigDto = iterator.next();
			faceSigDto.setFaceJobId(userCode);
			Integer faceSignCount = faceSigAppointmentDao.selectExistFacesignedCase(faceSigDto);
			if(faceSignCount<1){
				dto = faceSigDto;
				break;
			}
		}
		if(dto==null){
			throw new MarvelsBusinessException("无可取单"+userCode);
		}
		HandleProcessDTO handleProcessDTO = new HandleProcessDTO();
		List<String> queryNodes = new ArrayList<String>();
		queryNodes.add(CaseNodeConstant.WOINTERVIEW.getCode());
		handleProcessDTO.setQueryNodes(queryNodes);
		handleProcessDTO.setLoanId(dto.getLoanId());
		LoanApplyCaseDTO loanApplyCase = processService.handleProcess(handleProcessDTO);
		if (loanApplyCase == null) {
			throw new MarvelsBusinessException("取件失敗" + loanApplyCase);
		}
		//取完件更新面签岗id
		FaceSigAppointmentDTO facesig = new FaceSigAppointmentDTO();
		facesig.setLoanId(loanApplyCase.getLoanId());
		facesig.setCreateBy(userCode);
		facesig.setFaceJobId(userCode);
		facesig.setFaceJobName(user.getUserName());
		count = faceSigAppointmentDao.updateFaceSignHandler(facesig);
		return count;
	}

	/**
	 * 获取用户权限
	 * 
	 * @throws MarvelsBusinessException
	 */
	@Override
	public SysUserDTO getUserCode() throws MarvelsBusinessException {
		UserDTO user = CacheUtils.getCacheUser();
		if (user == null) {
			throw new MarvelsBusinessException("无法获取登录信息,token:" + ThreadContextUtil.get("l-token"));
		}
		return iSysUserService.querySysUser(user.getUserId());
	}

	/**
	 * 获取所有用户
	 * 
	 * @return
	 * @throws MarvelsBusinessException
	 */
	@Override
	public List<SysUserDTO> getUserList() throws MarvelsBusinessException {
		return iSysUserService.getUserList();
	}

	/**
	 * 视频面签查询
	 * 
	 * @param faceSigAppointmentDTO
	 * @param pageNo
	 * @param pageSize
	 * @return
	 * @throws MarvelsBusinessException
	 */
	@Override
	public Page<FaceSigAppointmentDTO> getVideoFaceSigAppointmentPage(FaceSigAppointmentDTO faceSigAppointmentDTO,
			Integer pageNo, Integer pageSize) throws MarvelsBusinessException {
		if (pageNo <= 0) {
			pageNo = PageConstant.CURRPAGE;
		}
		if (pageSize <= 0) {
			pageSize = PageConstant.PAGESIZE;
		}
		PageHelper.startPage(pageNo, pageSize);
		String FaceSigStatus = faceSigAppointmentDTO.getFaceSigStatus();
		if(FaceSigStatus!=null && !"".equals(FaceSigStatus)){
			String [] status = FaceSigStatus.split(",");
			String [] list = new String[status.length];
			for (int i = 0; i <status.length; i++) {
				list[i] = status[i];
			}
			UserDTO user = CacheUtils.getCacheUser();  //从缓存中读取到用户
			String userCode = user.getUserCode() == null?MarvelsConstant.SYSTEM_USER : user.getUserCode();
			return faceSigAppointmentDao.selectVideoFaceSigPage(userCode,list);
		}
		return null;
	}

	/***
	 * 查詢预约时间
	 */
	@Override
	public FaceSigAppointmentDTO getRangeTime(String id) throws MarvelsBusinessException {
		return faceSigAppointmentDao.selectRangeTime(id);
	}

	/**
	 * 修改面签
	 */
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	@Override
	public Integer updateAppointment(FaceSigAppointmentDTO faceSigAppointmentDTO,Boolean isNeedQueryUser) throws MarvelsBusinessException {
		String userCode = MarvelsConstant.SYSTEM_USER;
		if(isNeedQueryUser){
			UserDTO user = CacheUtils.getCacheUser();  //从缓存中读取到用户
			userCode =user.getUserCode() == null?MarvelsConstant.SYSTEM_USER : user.getUserCode();
		}
		faceSigAppointmentDTO.setUpdateBy(userCode);
		faceSigAppointmentDTO.setCreateBy(userCode);
		return faceSigAppointmentDao.updateAppointment(faceSigAppointmentDTO);
	}

	@Override
	public Integer queryCount() throws MarvelsBusinessException {
		return faceSigAppointmentDao.queryCount();
	}

	@Override
	public Map<String, Object> queryHoliday(Map<String, Object> map) throws MarvelsBusinessException{
		return faceSigAppointmentDao.selectHoliday(map);
	}

	@Override
	public FaceSigAppointmentDTO selectByPrimaryKey(Integer appointmentId) throws MarvelsBusinessException {
		
		return faceSigAppointmentDao.selectByPrimaryKey(appointmentId);
	}

	@Override
	public Integer checkRepeartLoanId(String loanId) throws MarvelsBusinessException {
		return faceSigAppointmentDao.checkRepeartLoanId(loanId);
	}

	@Override
	public List<FaceSigAppointmentDTO> selectNeedTips() throws MarvelsBusinessException {
		return faceSigAppointmentDao.selectNeedTips();
	}
	
	@Transactional(timeout = 30 ,rollbackFor=Exception.class)
	@Override
	public Integer updateScanOutmoded() throws MarvelsBusinessException{
		return faceSigAppointmentDao.updateScanOutmoded();
	}

	@Override
	public Map<String, Object> queryAppointmentDetail(Integer appointmentId) throws MarvelsBusinessException {
		FaceSigAppointmentDTO faceSigAppointment = faceSigAppointmentDao.selectByPrimaryKey(appointmentId);
		List<SysUserDTO> userList = this.getUserList();
		Page<FaceSigConfigurationDTO> pageList = faceSigConfigurationService.selectStartTime();
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("faceSigAppointment", faceSigAppointment);
		result.put("userList", userList);
		result.put("timeList", pageList.getResult());
		return result;
	}

	@Override
	public FaceSigAppointmentDTO queryCancelStatus(Integer appointmentId) throws MarvelsBusinessException {
		return faceSigAppointmentDao.queryCancelStatus(appointmentId);
	}
	@Override
	@Transactional(timeout = 30 ,rollbackFor=Exception.class)
	public void doAppointment(ChannelUserDTO user,McamLoanApplyInfoDTO acLoanApplyInfo,Integer timeSlotId,Date date,String faceJobId,Boolean isNeedQueryUser) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("预约面签用户信息===========>>>"+user);
		try {
			FaceSigAppointmentDTO faceSigAppointmentParam = new FaceSigAppointmentDTO();
			faceSigAppointmentParam.setLoanId(acLoanApplyInfo.getLoanId());
			faceSigAppointmentParam.setCancel(1);
			faceSigAppointmentParam.setUserId(user.getId());
			faceSigAppointmentParam.setFaceSigStatus(FacesigOperationType.HAS_PASSED);
			Integer pageNo = 1;
			Integer pageSize = 100;
			List<FaceSigAppointmentDTO> list = this.getFaceSigAppointmentPage(faceSigAppointmentParam, pageNo, pageSize);
			for (FaceSigAppointmentDTO faceSigAppointment : list) {
				faceSigAppointment.setIsDelete(0);
				this.updateAppointment(faceSigAppointment,isNeedQueryUser);
			}
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error("updateAppointment==>>", e1);
		}
		LoanApplyCaseLogDTO caseLogDto =new LoanApplyCaseLogDTO();
		caseLogDto.setLoanId(acLoanApplyInfo.getLoanId());
		caseLogDto.setNodeCode(CaseNodeConstant.WOINTERVIEW.getCode());
		List<LoanApplyCaseLogDTO> loanCaseLogs = loanApplyCaseLogDao.selectLoanApplyCaseLog(caseLogDto);
		if(CollectionUtils.isEmpty(loanCaseLogs)){
			throw new MarvelsBusinessException("无面签环节的日志记录");
		}
		Date rangeTime = loanCaseLogs.get(0).getStartTime();

		FaceSigAppointmentDTO faceSigAppointment = new FaceSigAppointmentDTO();
		faceSigAppointment.setRangeTime(rangeTime);
		faceSigAppointment.setUserId(user.getId());
		faceSigAppointment.setAppointmentDate(date);
		faceSigAppointment.setTimeId(timeSlotId);
		faceSigAppointment.setLoanId(acLoanApplyInfo.getLoanId());
		faceSigAppointment.setCancel(1);
		faceSigAppointment.setFaceSigStatus(FacesigOperationType.NOT_SIGN_FACE_TO_FACE);

		faceSigAppointment.setCustName(acLoanApplyInfo.getCustName());
		faceSigAppointment.setCustIdcard(acLoanApplyInfo.getCustCardNo());
		faceSigAppointment.setClientManager(user.getRealName());

		CmsEmployeeInfoDTO cmsEmployeeInfo = consumerUmApi.queryEmployeeByUserId(user.getId());

		if (cmsEmployeeInfo != null) {
			 faceSigAppointment.setClientManagerEmployeeNo(acLoanApplyInfo.getEmployeeId());
		}

		faceSigAppointment.setcId(user.getCid());
		faceSigAppointment.setChannelType(acLoanApplyInfo.getChannel());
		faceSigAppointment.setPrincipalAmtAct(acLoanApplyInfo.getPrincipalAmtAct());

		try {
			String updatedBy = null;
			if(!isNeedQueryUser){
				updatedBy = MarvelsConstant.USER;
			}
			int count= mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(acLoanApplyInfo.getLoanId(), LoanStateConstant.P02, null, updatedBy);
			if (count < 1) {// 视频面签已预约
				throw new MarvelsBusinessException("修改贷款单失败!");
			}
			faceSigAppointment.setCreateTime(new Date());
			String time = new Date().getTime() + "";
			Integer timeq = Integer.valueOf(time.substring(6, 10)) + 1;// 总是会慢一秒
			// 房间号为预约创建时间戳 秒的后4位加上客户手机号码的后5位
			String roomId = timeq + acLoanApplyInfo.getMobileNo().substring(6);
			faceSigAppointment.setRoomId(roomId);
			if(!StringUtils.isEmpty(faceJobId)){
				faceSigAppointment.setFaceJobId(faceJobId);
			}
			MarvelsLogUtil.getInstance().info("预约面签faceSigAppointment===========>>>"+faceSigAppointment);
			faceSigAppointmentDao.addFacesigTask(faceSigAppointment);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("faceSigAppointmentService.insertSelective", e);
			throw new MarvelsBusinessException("预约失败!");
		}
		
	}

	@Override
	public List<SysUserDTO> selectFaceSignUsers() throws MarvelsBusinessException {
		List<SysUserDTO> users = iSysUserService.selectUserByRoleCode(ServerProperties.getValue(propertiesPath, "resource.properties", "visa.rolecode"));
		if(CollectionUtils.isEmpty(users)){
			throw new MarvelsBusinessException("面签岗下没有人员");
		}
		return users;
	}

	@Override
	public Integer queryDateTimeCount(FaceSigAppointmentDTO faceSigAppointmentDto) throws MarvelsBusinessException {
		return faceSigAppointmentDao.queryDateTimeCount(faceSigAppointmentDto);
	}
}
